package top.infopub.util.security;


import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;


/**
 * AesUtil
 * @author Awoke
 * @version 2018年9月14日
 * @see AesUtil
 * @since
 */
@Component
public class AesUtil {

    private static final Logger log = LoggerFactory.getLogger(AesUtil.class);

    private static final String ENCODING = "UTF-8";

    private static final String CRYPTOGRAPHIC_ALGORITHM = "AES";

    private static final String SECURERANDOM_ALGORITHM = "SHA1PRNG";

    @Value("${common.aes.key:not-configured}")
    private String AES_KEY;

    /**
     * 加密
     */
    public String encryptByKey(String content) {
        if (StringUtils.isBlank(content)) {
            return null;
        }
        content = content.trim();// 去除前后空格
        try {
            SecureRandom secureRandom = SecureRandom.getInstance(SECURERANDOM_ALGORITHM);
            secureRandom.setSeed(AES_KEY.getBytes(ENCODING));
            KeyGenerator kgen = KeyGenerator.getInstance(CRYPTOGRAPHIC_ALGORITHM);
            kgen.init(128, secureRandom);
            SecretKey secretKey = kgen.generateKey();
            byte[] keyb = secretKey.getEncoded();
            SecretKeySpec sks = new SecretKeySpec(keyb, CRYPTOGRAPHIC_ALGORITHM);
            Cipher ecipher = Cipher.getInstance(CRYPTOGRAPHIC_ALGORITHM);// 创建加密密码器
            ecipher.init(Cipher.ENCRYPT_MODE, sks);
            byte[] byteContent = content.getBytes(ENCODING);
            byte[] result = ecipher.doFinal(byteContent);
            return parseByte2HexStr(result); // 16进制的转换
        }
        catch (Exception e) {
            log.error("", e);
            return null;
        }
    }

    /**
     * 解密
     */
    public String decryptByKey(String content) {
        if (StringUtils.isBlank(content)) {
            return null;
        }
        try {
            SecureRandom secureRandom = SecureRandom.getInstance(SECURERANDOM_ALGORITHM);
            secureRandom.setSeed(AES_KEY.getBytes(ENCODING));
            KeyGenerator kgen = KeyGenerator.getInstance(CRYPTOGRAPHIC_ALGORITHM);
            kgen.init(128, secureRandom);
            SecretKey secretKey = kgen.generateKey();
            byte[] keyb = secretKey.getEncoded();
            SecretKeySpec sks = new SecretKeySpec(keyb, CRYPTOGRAPHIC_ALGORITHM);
            Cipher dcipher = Cipher.getInstance(CRYPTOGRAPHIC_ALGORITHM);// 创建加密密码器
            dcipher.init(Cipher.DECRYPT_MODE, sks);
            byte[] contentTemp = parseHexStr2Byte(content); // 将16进制字符串变为加密字符串
            byte[] result = dcipher.doFinal(contentTemp);
            return new String(result, ENCODING);
        }
        catch (Exception e) {
            log.error("", e);
            return null;
        }
    }

    /**
     * 转化字符串为十六进制编码
     * @return
     */
    public String stringToHex(String s) {
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < s.length(); i++ ) {
            str.append(Integer.toHexString((int)s.charAt(i)));
        }
        return str.toString();
    }

    /**
     * 转化十六进制编码为字符串
     * @return
     */
    public String hexToString(String s) {
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++ ) {
            try {
                baKeyword[i] = (byte)(0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
            }
            catch (Exception e) {
                log.error("", e);
            }
        }
        try {
            s = new String(baKeyword, ENCODING);
        }
        catch (Exception e1) {
            log.error("", e1);
        }
        return s;
    }

    /**
     * 将16进制转换为二进制
     * @return
     */
    public byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1) return null;
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++ ) {
            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
            result[i] = (byte)(high * 16 + low);
        }
        return result;
    }

    /**
     * 将二进制转换成16进制
     * @param buf
     * @return
     */
    public String parseByte2HexStr(byte buf[]) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++ ) {
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex);
        }
        return sb.toString();
    }

}
